-- SPDX-FileCopyrightText: Adam Evyčędo
--
-- SPDX-License-Identifier: AGPL-3.0-or-later

---@diagnostic disable-next-line: unused-local, lowercase-global
function getUpdates(tripID, sequence, stopID, stopCode)
	local http = require("http")
	local json = require("json")

	local error_struct = {
		httpResponseCode = 0,
		message = "",
		willNextRequestFail = false
	}

	local platform = ""
	local dhid = ""
	local i = 0
	for m in string.gmatch(stopCode, "([^_]+)") do
		if i == 0 then
			dhid = m
		end
		if i == 1 then
			platform = m
			break
		end
		i = i + 1
	end

	local ibnr = ""
	i = 0
	for m in string.gmatch(dhid, "([^:]+)") do
		if i == 2 then
			ibnr = m
			break
		end
		i = i + 1
	end

	local response, error_message = http.get("https://v6.vbb.transport.rest/stops/" .. ibnr .. "/departures", {
		query = "duration=60&results=144&pretty=false",
		timeout = "30s"
	})

	if response == nil then
		error_struct.message = "while getting updates: " .. error_message
		local error_json, _ = json.encode(error_struct)
		return "", error_json
	end

	if response.status_code ~= 200 then
		error_struct.message = "api returned code " .. response.status_code .. "; " .. response.body
		error_struct.httpResponseCode = response.status_code
		error_struct.willNextRequestFail = true
		local error_json, _ = json.encode(error_struct)
		return "", error_json
	end

	---@diagnostic disable-next-line: redefined-local
	local struct, error_message = json.decode(response.body)

	if struct == nil then
		error_struct.message = "while decoding updates: " .. error_message
		local error_json, _ = json.encode(error_struct)
		return "", error_json
	end

	local updates = {
		areTripsInTimetable = false,
		updates = {},
		alerts = {}
	}
	updates.updates[''] = {
		time = "000000",
		stopID = stopCode,
		delay = 0,
		timetableRelationship = 1,
		vehicleStatus = {
			lineName = "",
			headsign = ""
		}
	}
	updates.alerts[''] = { {
		timeRanges = {
			{ startDate = '0001-01-01T00:00:00.000Z', endDate = '9999-12-31T23:59:59.999Z' }
		},
		headers = {
			und = ''
		},
		descriptions = {
			und = ''
		},
		urls = {
			und = ''
		},
		cause = 0,
		effect = 0
	} }


	for _, entry in ipairs(struct.departures) do
		local stationIBNR = ""
		i = 0
		for m in string.gmatch(entry.stop.stationDHID, "([^:]+)") do
			if i == 2 then
				stationIBNR = m
				break
			end
			i = i + 1
		end

		if stationIBNR == ibnr and entry.platform == platform then
			updates.updates[entry.tripId] = {
				time = string.sub(entry.when, 12, 13) .. string.sub(entry.when, 15, 16) .. string.sub(entry.when, 18, 19),
				stopID = stopCode,
				delay = entry.delay,
				timetableRelationship = 1,
				vehicleStatus = {
					lineName = entry.line.name,
					headsign = entry.destination.name,
				}
			}
			local j = 1
			for _, remark in ipairs(entry.remarks) do
				if remark.type == 'warning' then
					if updates.alerts[entry.tripId] == nil then
						updates.alerts[entry.tripId] = {}
					end
					updates.alerts[entry.tripId][j] = {
						timeRanges = {
							{
								startDate = string.sub(remark.validFrom, 1, 19) .. '.000' .. string.sub(remark.validFrom, 20, 25),
								endDate = string.sub(remark.validUntil, 1, 19) .. '.000' .. string.sub(remark.validUntil, 20, 25)
							}
						},
						headers = {
							und = remark.summary
						},
						descriptions = {
							und = remark.text
						}
					}
					j = j + 1
				end
			end
			if entry.currentTripPosition ~= nil then
				updates.updates[entry.tripId].vehicleStatus.latitude = entry.currentTripPosition.latitude
				updates.updates[entry.tripId].vehicleStatus.longitude = entry.currentTripPosition.longitude
			end
		end
	end

	---@diagnostic disable-next-line: redefined-local
	local result, error_message = json.encode(updates)

	if result == nil then
		error_struct.message = "while encoding result: " .. error_message
		local error_json, _ = json.encode(error_struct)
		return "", error_json
	end

	return result, ""
end
